tmem: fix corner case crash on forcible domain destruction
authorKeir Fraser <keir.fraser@citrix.com>
Mon, 1 Jun 2009 13:07:46 +0000 (14:07 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Mon, 1 Jun 2009 13:07:46 +0000 (14:07 +0100)
When a tmem-enabled domain is destroyed, if the domain was
using a persistent pool, the domain destruction process
to scrubs page races tmem's attempts to gracefully dismantle
data structures.  Move tmem_destroy earlier in the domain
destruction process.

Signed-off-by: Dan Magenheimer <dan.magenheimer@oracle.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen/common/domain.c
xen/common/tmem.c

index 50dd43655d4483e32f20249481b9d25f0c4094f3..0bce563331acc5c861fe98cc8e3449a67598eec6 100644 (file)
@@ -402,6 +402,8 @@ int domain_kill(struct domain *d)
         spin_barrier(&d->domain_lock);
         evtchn_destroy(d);
         gnttab_release_mappings(d);
+        tmem_destroy(d->tmem);
+        d->tmem = NULL;
         /* fallthrough */
     case DOMDYING_dying:
         rc = domain_relinquish_resources(d);
@@ -583,9 +585,6 @@ static void complete_domain_destroy(struct rcu_head *head)
 
     grant_table_destroy(d);
 
-    if ( d->tmem != NULL )
-        tmem_destroy(d->tmem);
-
     arch_domain_destroy(d);
 
     rangeset_domain_destroy(d);
index 0ab7b55c8691cf921166fc69b607d8e568614db9..e40bc64505402021e22974da92758637fcb0cad4 100644 (file)
@@ -867,7 +867,6 @@ static void client_free(client_t *client)
 {
     list_del(&client->client_list);
     tmh_client_destroy(client->tmh);
-    tmh_set_current_client(NULL);
     tmem_free(client,sizeof(client_t),NULL);
 }
 
@@ -1992,20 +1991,17 @@ EXPORT void tmem_destroy(void *v)
 {
     client_t *client = (client_t *)v;
 
+    if ( client == NULL )
+        return;
+
     if ( tmh_lock_all )
         spin_lock(&tmem_spinlock);
     else
         write_lock(&tmem_rwlock);
 
-    if ( client == NULL )
-        printk("tmem: can't destroy tmem pools for %s=%d\n",
-               cli_id_str,client->cli_id);
-    else
-    {
-        printk("tmem: flushing tmem pools for %s=%d\n",
-               cli_id_str,client->cli_id);
-        client_flush(client,1);
-    }
+    printk("tmem: flushing tmem pools for %s=%d\n",
+           cli_id_str, client->cli_id);
+    client_flush(client, 1);
 
     if ( tmh_lock_all )
         spin_unlock(&tmem_spinlock);